package cn.stylefeng.guns.modular.bulletin.service;


import cn.stylefeng.guns.core.common.page.LayuiPageFactory;
import cn.stylefeng.guns.core.exceptions.BusinessException;
import cn.stylefeng.guns.modular.app.entity.Member;
import cn.stylefeng.guns.modular.base.state.F;
import cn.stylefeng.guns.modular.base.state.ProConst;
import cn.stylefeng.guns.modular.base.util.RedisUtil;
import cn.stylefeng.guns.modular.base.util.Result;
import cn.stylefeng.guns.modular.bulletin.entity.Subscribe;
import cn.stylefeng.guns.modular.bulletin.entity.SubscribeRecords;
import cn.stylefeng.guns.modular.bulletin.mapper.SubscribeRecordsMapper;
import cn.stylefeng.guns.modular.fin.entity.Currency;
import cn.stylefeng.guns.modular.fin.service.CurrencyService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class SubscribeRecordsService extends ServiceImpl<SubscribeRecordsMapper, SubscribeRecords> {

    @Resource
    private CurrencyService currencyService;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private SubscribeService subscribeService;


    @Resource
    private TransactionTemplate transactionTemplate;

    public Page<Map<String, Object>> selectByCondition(String name, String account) {
        Page page = LayuiPageFactory.defaultPage();
        return this.baseMapper.selectByCondition(page, name,account);
    }


    public SubscribeRecords getSubscribeRecords(Long memberId,String coinName){
        LambdaQueryWrapper<SubscribeRecords> lqm = new LambdaQueryWrapper<>();
        lqm.eq(SubscribeRecords::getUid,memberId);
        lqm.eq(SubscribeRecords::getSubscriptionCurrencyName,coinName);
        return this.getOne(lqm,false);
    }


    public List<SubscribeRecords> getWaitOnLineSubscribeRecordsList(String coinName){
        LambdaQueryWrapper<SubscribeRecords> lqm = new LambdaQueryWrapper<>();
        lqm.eq(SubscribeRecords::getStatus,'0');
        lqm.eq(SubscribeRecords::getSubscriptionCurrencyName,coinName);
        return this.list(lqm);
    }



    public Result subscribeRecords(String token, Integer pageIndex, Integer pageSize) {

        IPage<SubscribeRecords> page = new Page<>(pageIndex,pageSize);

        Member member = (Member) redisUtil.get(token);
        Assert.notNull(member, "用户不存在或未登录");
        SubscribeRecords subscribeRecordsQ = new SubscribeRecords();
        subscribeRecordsQ.setUid(member.getMemberId());
        subscribeRecordsQ.setStatus("0");
        return Result.success(this.page(page,new QueryWrapper<>(subscribeRecordsQ)));
    }


    public Result submitSubscribe(String token, Long sid, Integer amount) {
        Member member = (Member) redisUtil.get(token);
        Assert.notNull(member, "用户不存在或未登录");
        Subscribe subscribe = subscribeService.getById(sid);
        Assert.notNull(subscribe, "认购币种不存在");
        //扣除金额
        BigDecimal subscribePrice = subscribe.getIssuePrice().multiply(BigDecimal.valueOf(amount));
        //钱包账户
        Currency usdtCurrency = F.me().getCurrency(member.getMemberId(), "USDT");
        if(usdtCurrency.getUsedPrice().compareTo(subscribePrice) < 0){
            throw new BusinessException("申购币种余额不足支付"+ subscribePrice);
        }

        SubscribeRecords hasSubscribeRecords = this.getSubscribeRecords(member.getMemberId(), subscribe.getCoinName());
        if(hasSubscribeRecords != null){
            throw new BusinessException("该币种您已申购");
        }
        SubscribeRecords subscribeRecords = new SubscribeRecords();
        subscribeRecords.setCreateTime(new Date());
        subscribeRecords.setUid(member.getMemberId());
        subscribeRecords.setPaymentAmount(subscribePrice);
        subscribeRecords.setPaymentCurrency("USDT");
        subscribeRecords.setSubscriptionCurrencyAmount(BigDecimal.valueOf(amount));
        subscribeRecords.setSubscriptionCurrencyName(subscribe.getCoinName());
        subscribeRecords.setSubscriptionTime(new Date());
        subscribeRecords.setStatus("0");


       F.me().getCurrency(member.getMemberId(),subscribe.getCoinName() );

        Boolean execute =   transactionTemplate.execute(e->{
            boolean ok = this.save(subscribeRecords);
            if(ok){
                ok = currencyService.operateCurrencyUsedPrice(usdtCurrency.getMemberId(), usdtCurrency.getType(), ProConst.CashFlowOpEnum.FLOW_OUT,subscribePrice,usdtCurrency.getUsedPrice(),"申购"+subscribe.getCoinName());
            }
            if(!ok){
                e.setRollbackOnly();
                throw new BusinessException("申购失败");
            }
            return ok;
        });
        return Result.success("申购成功");
    }




    public Boolean onLine(SubscribeRecords subscribeRecords,BigDecimal subscribePrice){

        subscribeRecords.setStatus("1");
        this.updateById(subscribeRecords);
        if(subscribeRecords.getLuckyCurrencyAmount().compareTo(BigDecimal.ZERO) <1){
            return true;
        }
        String coinName = subscribeRecords.getSubscriptionCurrencyName().split("/")[0];

       Currency currency = F.me().getCurrency(subscribeRecords.getUid(), coinName);

      Boolean ok = currencyService.operateCurrencyUsedPrice(subscribeRecords.getUid(), coinName, ProConst.CashFlowOpEnum.FLOW_IN, subscribeRecords.getLuckyCurrencyAmount(),"中签");

        if(ok){

            BigDecimal subtract = subscribeRecords.getSubscriptionCurrencyAmount().subtract(subscribeRecords.getLuckyCurrencyAmount());

            //返还差价
            if(subtract.compareTo(BigDecimal.ZERO) > 0){
                 ok = currencyService.operateCurrencyUsedPrice(subscribeRecords.getUid(), subscribeRecords.getPaymentCurrency(), ProConst.CashFlowOpEnum.FLOW_IN, subtract.multiply(subscribePrice),"申购返还");
            }

        }
        return ok;

    }


}
